package gbench.sandbox.matlib;

import org.junit.jupiter.api.Test;

import gbench.common.matlib.MatlibCanvas.NVec;
import gbench.common.matlib.MatlibCanvas.PatternCase;
import gbench.common.matlib.matrix.XXVec;
import gbench.common.matlib.rdd.BasePair;
import java.util.function.Function;

import static gbench.common.matlib.MatlibCanvas.PatternCase.defaultcase;
import static gbench.common.matlib.MatlibCanvas.PatternCase.nullcase;
import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.matlib.data.Pipe.NULL;
import static gbench.common.matlib.rdd.BasePair.bp;
import static gbench.common.matlib.rdd.PVec.pvec2clc;
import static gbench.common.tree.LittleTree.IRecord.REC;
import static gbench.common.tree.LittleTree.KVPair.kvpSclc;
import static java.lang.Math.random;

/**
 * 高阶 XVec 对象
 */
public class JunitXXVec {

    /**
     * 对角矩阵
     */
    @Test
    public void diagonal() {
        println("diagonal");
        final var diagonal = XXVec.OF(10, 10, (i, j) -> i.equals(j) ? 1 : 0) // 对角矩阵的稀疏矩阵
                .mutateX((e) -> new XXVec<Integer,Object>(e) {
                    @Override
                    public Object duplicate(Integer[][] dd) {
                        return null; // 不予实现
                    } // duplicate
                }); // mutateX

        // 数据打印
        diagonal.dataStream(e -> e.flatten((Function<Double[], NVec>) NVec::new,
                nullcase(0d).typeof2((Number) null, Number::doubleValue).fn())
        ).forEach(e -> println(e));
    }

    /**
     * 模式识别
     */
    @Test @SuppressWarnings("unchecked")
    public void pattern_matching() {
        println("pattern_matching");
        final var num_pattern = PatternCase.<Object, Double>nullcase(0d) // 数字模式
                .typeof(Number.class, Number::doubleValue); // pattern 的识别器
        final var nvecctor = (Function<Double[], NVec>) NVec::new; // NVec 的构建器

        XXVec.OF(5, 5, (i, j) -> bp(i, j).append(random()))
                .flatX(BasePair.class) // 扁平化成 BasePair 序列
                .forEach(p -> println(p.flatten(nvecctor, num_pattern))); // BasePair 扁平化成 NVec 向量

        println("\nIRecord 等价于  PatternCase<String,Object>");
        final var rec = REC("name", "zhangsan", "sex", "man", "adrress", "shanghai");
        println("【",rec,"】数据项目字段遍历");
        final var none = NULL(String.class); // String 类型的NULL
        final var caserec = rec.collect(kvpSclc(ss -> ss.reduce(defaultcase(none, "default value"),
                (aa, a) -> aa.eq(a._1(), a._2().toString()), (a, b) -> a.merge(b))));
        rec.keys().forEach(name -> println(name, "---->", caserec.eval(name)));
        println("\ncaserec.eval() :", caserec.eval());
        println("caserec 的toString 相当于caserec.eval().toString() :", caserec);
        println(caserec.stream().collect(pvec2clc()));
    }
}
